#include "tcpclient.h"
#include "./ui_tcpclient.h"
#include <QByteArray>
#include <QDebug>
#include <QMessageBox>
#include <QHostAddress>

TcpClient::TcpClient(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::TcpClient)
{
    ui->setupUi(this);
    loadConfig();

    // 绑定槽函数
    connect(&m_tcpSocket,SIGNAL(connected()), this, SLOT(showConnect()));

    connect(&m_tcpSocket,SIGNAL(readyRead()), this, SLOT(recvMsg()));

    // 连接服务器
    m_tcpSocket.connectToHost(QHostAddress(m_strIP),m_usPort);
}

TcpClient::~TcpClient()
{
    delete ui;
}

void TcpClient::loadConfig()
{
    QFile file(":/client.config");
    if(file.open(QIODevice::ReadOnly)){
        QByteArray baData = file.readAll();
        QString strData = baData.toStdString().c_str();
        file.close();

        strData.replace("\r\n"," ");

        QStringList strList = strData.split(" ");
        m_strIP = strList.at(0);
        m_usPort = strList.at(1).toUShort();
        qDebug() << "ip:" << m_strIP << " port:" << m_usPort;
    }else {
        QMessageBox::critical(this,"open config","open config failed");
    }
}

TcpClient &TcpClient::getInstance()
{
    static TcpClient instance;
    return instance;
}

QTcpSocket &TcpClient::getTcpSocket()
{
    return m_tcpSocket;
}

QString TcpClient::loginName()
{
    return m_strLoginName;
}

void TcpClient::showConnect()
{
    QMessageBox::information(this,"连接服务器","连接服务器成功");
}

void TcpClient::recvMsg()
{
    qDebug() << m_tcpSocket.bytesAvailable();
    uint uiPDULen = 0;
    m_tcpSocket.read((char*)&uiPDULen,sizeof(uint));
    uint uiMsgLen = uiPDULen - sizeof(PDU); // 实际消息长度
    PDU *pdu = mkPDU(uiMsgLen);
    m_tcpSocket.read((char*)pdu + sizeof(uint),uiPDULen - sizeof(uint)); // 读取，填充除了uiPDULen属性的其他部分.

    switch(pdu->uiMsgType) {
        case ENUM_MSG_TYPE_REGIST_RESPOND: {
            if(0 == strcmp(pdu->caData, REGIST_OK)){
                QMessageBox::information(this,"注册",REGIST_OK);
            }else if(0 == strcmp(pdu->caData, REGIST_FAILED)) {
                QMessageBox::information(this,"注册",REGIST_FAILED);
            }
            break;
        }
        case ENUM_MSG_TYPE_LOGIN_RESPOND: {
            if(0 == strcmp(pdu->caData, LOGIN_OK)){
                QMessageBox::information(this,"登录",LOGIN_OK);
                OpeWidget::getInstance().show();
                this->hide();
            }else if(0 == strcmp(pdu->caData, LOGIN_FAILED)) {
                QMessageBox::information(this,"登录",LOGIN_FAILED);
            }
            break;
        }
        case ENUM_MSG_TYPE_ALL_ONLINE_RESPOND: {
            OpeWidget::getInstance().getFriend()->showAllOnlineUsr(pdu);
            break;
        }
        case ENUM_MSG_TYPE_SEARCH_USR_RESPOND: {
            if(0 == strcmp(SEARCH_USR_NO, pdu->caData)) {
                QMessageBox::information(this, "搜索", QString("%1: not exist").arg(OpeWidget::getInstance().getFriend()->m_strSearchName));
            } else if(0 == strcmp(SEARCH_USR_ONLINE, pdu->caData)) {
                QMessageBox::information(this, "搜索", QString("%1: online").arg(OpeWidget::getInstance().getFriend()->m_strSearchName));
            } else if(0 == strcmp(SEARCH_USR_OFFLINE, pdu->caData)) {
                QMessageBox::information(this, "搜索", QString("%1: offline").arg(OpeWidget::getInstance().getFriend()->m_strSearchName));
            }
            break;
        }
        case ENUM_MSG_TYPE_ADD_FRIEND_REQUEST: {
            char caName[32] = {'\0'};
            strncpy(caName, pdu->caData+32, 32);
            int ret = QMessageBox::information(this,"添加好友",QString("%1 want to add you as friend ?").arg(caName),
                        QMessageBox::Yes, QMessageBox::No);
            // 同意与否
            PDU *respdu = mkPDU(0);
            memcpy(respdu->caData, pdu->caData, 32); // 被添加人姓名
            memcpy(respdu->caData+32, caName, 32); // 申请人姓名
            if(QMessageBox::Yes == ret) {
                respdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_AGREE;
            } else {
                respdu->uiMsgType = ENUM_MSG_TYPE_ADD_FRIEND_REFUSE;
            }
            m_tcpSocket.write((char*)respdu, respdu->uiPDULen);
            free(respdu);
            respdu = NULL;
            break;
        }
        case ENUM_MSG_TYPE_ADD_FRIEND_RESPOND: {
            QMessageBox::information(this, "添加好友", pdu->caData);
            break;
        }
        case ENUM_MSG_TYPE_ADD_FRIEND_AGREE_RESPONSE: {
            char caPername[32] = {'\0'};
            strncpy(caPername, pdu->caData, 32);
            QString message = QString("成功添加 %1 为好友").arg(caPername);
            QMessageBox::information(this, "添加好友", message);
            break;
        }
        case ENUM_MSG_TYPE_ADD_FRIEND_REFUSE_RESPONSE: {
            char caPername[32] = {'\0'};
            strncpy(caPername, pdu->caData, 32);
            QString message = QString("%1 拒绝添加您为好友").arg(caPername);
            QMessageBox::information(this, "添加好友", message);
            break;
        }
        case ENUM_MSG_TYPE_FLUSH_FRIEND_RESPOND: {
            OpeWidget::getInstance().getFriend()->updateFriendList(pdu);
            break;
        }
        case ENUM_MSG_TYPE_DELETE_FRIEND_RESPOND: {
            char friendName[32] = {'\0'};
            strncpy(friendName, pdu->caData + 32, 32);
            QString message = QString("成功删除好友 %1").arg(friendName);
            // 重新刷新好友列表
            emit Friend::getInstance().getRefreshFriendButton()->clicked(true);
            QMessageBox::information(this, "删除好友", message);
            break;
        }
        default:{
            break;
        }
    }

    free(pdu);
    pdu = NULL;
}


# if 0
void TcpClient::on_send_pb_clicked()
{
    QString strMsg = ui->lineEdit->text();
    // 发送数据
    if(!strMsg.isEmpty()) {
        // 1.创建报文
        PDU *pdu = mkPDU(strMsg.size());
        pdu->uiMsgType = 8888;
        memcpy(pdu->caMsg,strMsg.toStdString().c_str(),strMsg.size());
        // 2.发送报文
        m_tcpSocket.write((char*)pdu,pdu->uiPDULen);
        // 3.销毁报文空间
        free(pdu);
        pdu = NULL;
    }else {
        QMessageBox::warning(this,"信息发送","发送的信息不能为空");
    }
}
# endif

// 登录
void TcpClient::on_login_pb_clicked()
{
    QString strName = ui->name_line->text();
    QString strPwd = ui->pwd_line->text();
    if(!strName.isEmpty() && !strPwd.isEmpty()) {
        m_strLoginName = strName;
        PDU *pdu = mkPDU(0);
        pdu->uiMsgType = ENUM_MSG_TYPE_LOGIN_REQUEST;
        strncpy(pdu->caData,strName.toStdString().c_str(),32);
        strncpy(pdu->caData+32,strPwd.toStdString().c_str(),32);
        m_tcpSocket.write((char*)pdu,pdu->uiPDULen);
        // 销毁报文空间
        free(pdu);
        pdu = NULL;
    }else {
        QMessageBox::critical(this,"登录","登录失败:用户名或者密码错误");
    }
}

// 注册
void TcpClient::on_regist_pb_clicked()
{
    QString strName = ui->name_line->text();
    QString strPwd = ui->pwd_line->text();
    if(!strName.isEmpty() && !strPwd.isEmpty()) {
        PDU *pdu = mkPDU(0);
        pdu->uiMsgType = ENUM_MSG_TYPE_REGIST_REQUEST;
        strncpy(pdu->caData,strName.toStdString().c_str(),32);
        strncpy(pdu->caData+32,strPwd.toStdString().c_str(),32);
        m_tcpSocket.write((char*)pdu,pdu->uiPDULen);
        // 销毁报文空间
        free(pdu);
        pdu = NULL;
    }else {
        QMessageBox::critical(this,"注册","注册失败:用户名或者密码为空");
    }
}

// 注销
void TcpClient::on_logout_pb_clicked()
{

}

